<template>
  <div class="query-row" :class="searchData.containerClass">
    <div v-if="isShowOperateContainer" class="operation-btns">
      <el-button
        v-if="isShowAddBtn"
        v-permissions="{ permission: ['add:' + pageName] }"
        :icon="Plus"
        type="primary"
        @click="onHandleAdd"
      >
        新增
      </el-button>

      <el-button
        v-if="isShowDelsBtn"
        v-permissions="{ permission: ['delAll:' + pageName] }"
        :icon="Delete"
        type="danger"
        @click="onHandleDel"
      >
        批量删除
      </el-button>
      <el-button v-if="isOperateRefreshBtn" :icon="Refresh" :loading="refreshLoading" type="primary" @click="onHandleRefresh">
        刷新
      </el-button>
      <slot name="extendOperate"></slot>
    </div>
    <div class="search-btns">
      <div class="query-input-rows">
        <template v-if="(querys && querys.length) || dataPerm.dataType">
          <template v-if="dataPerm.dataType == 0">
            <el-select v-model="queryForm.IN_orgid" multiple>
              <el-option v-for="item in orgList" :key="item.orgId" :label="item.orgName" :value="item.orgId" />
            </el-select>
          </template>
          <template v-if="dataPerm.dataType == 1">
            <el-checkbox-group v-model="queryForm.EQ_cr" disabled>
              <el-checkbox v-for="item in userIds" :key="item" :label="item"> 仅自己 </el-checkbox>
            </el-checkbox-group>
          </template>
          <template v-for="(item, index) in querys" :key="index">
            <div v-if="item.type === FormStyle.SLOT">
              <slot :name="item.slotName"></slot>
            </div>
            <template v-else>
              <SearchItem
                v-model="queryForm"
                :item="item"
                @on-handle-change-value="onHandleChangeValue"
                @on-handle-query-data="queryData"
              />
            </template>
          </template>

          <el-button
            v-if="isShowSearchBtn"
            class="search-btn"
            :icon="Search"
            :loading="searchLoading"
            type="primary"
            @click="queryData"
          >
            查询
          </el-button>
        </template>
        <div class="query-btn-rows">
          <el-button v-if="isShowRefreshBtn" :icon="Refresh" :loading="refreshLoading" type="primary" @click="onHandleRefresh">
            刷新
          </el-button>
          <slot name="extendOtherOperate"></slot>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { getList, doDelete, queryList } from "@/api/mains";
import { Search, Refresh, Delete, Plus } from "@element-plus/icons-vue";
import { useUserStore } from "@/stores/modules/user";
import { operateType } from "../commonType.enum";
import { FormStyle } from "../commonType.enum";
import { succMsg, failMsg } from "@/utils/MessageUtils";
import { ElLoading } from "element-plus";
import SearchItem from "./searchItem.vue";
import { storeToRefs } from "pinia";
import { useRoute } from "vue-router";
import mitt from "mitt";
import _ from "lodash";

export default defineComponent({
  name: "CommonSearch",
  components: {
    SearchItem
  },
  props: {
    modelValue: {
      type: Object,
      default: () => {
        return {};
      }
    },
    searchData: {
      type: Object,
      default: () => {
        return {};
      }
    },
    isLoading: {
      type: Boolean,
      default: false
    }
  },
  emits: {
    "update:model-value": null,
    "update:is-loading": null,
    "fetched-data": null,
    "handle-edit-info": null,
    "refresh-data": null,
    "on-handle-change-value": null
  },
  setup(props, { emit, expose }) {
    const _emitter = mitt();

    const $subFunc = () => {
      // eslint-disable-next-line prefer-rest-params
      Reflect.apply(_emitter.on, _emitter, _.toArray(arguments));
    };

    const $unsubFunc = () => {
      // eslint-disable-next-line prefer-rest-params
      Reflect.apply(_emitter.off, _emitter, _.toArray(arguments));
    };

    const userStore = useUserStore();
    const { orgid } = storeToRefs(userStore);
    const route = useRoute();
    const { proxy } = getCurrentInstance();
    // const $sub = inject("$sub");
    // const $unsub = inject("$unsub");
    const {
      querys,
      searchBtns,
      operationBtns = ref({}),
      queryUrl = ref(""),
      selectionIds,
      customFetch,
      doRefresh = ref(true)
    } = toRefs(props.searchData);

    const searchLoading = ref(props.isLoading);
    const queryForm = ref({ ...props.modelValue });
    const refreshLoading = ref(false);
    const isUrlHasQuery = ~queryUrl.value.indexOf("/");

    const { dataPerm = {} } = route?.meta || {};

    /**
     * 页面路由名字
     */
    const pageName = computed(() => {
      return route.name;
    });

    /**
     * 机构列表
     */
    const orgList = computed(() => {
      return dataPerm.orgList || [];
    });

    /**
     * 用户id
     */

    const userIds = computed(() => {
      return [dataPerm.userId];
    });

    /**
     * 搜索按钮
     */

    const isShowSearchBtn = computed(() => {
      const { searchBtnInfo = {} } = searchBtns?.value || {};
      const isShow = searchBtnInfo.isShow ?? true;
      return isShow;
    });

    /**
     * 搜索后面刷新按钮按钮
     */

    const isShowRefreshBtn = computed(() => {
      const { refreshBtnInfo } = searchBtns?.value || {};
      return refreshBtnInfo && refreshBtnInfo.isShow;
    });

    /**
     * 新增按钮
     */

    const isShowAddBtn = computed(() => {
      const { addBtnInfo } = operationBtns.value || {};
      return addBtnInfo && addBtnInfo.isShow;
    });

    /**
     * 批量删除按钮
     */

    const isShowDelsBtn = computed(() => {
      const { DelsBtnInfo } = operationBtns.value || {};
      return DelsBtnInfo && DelsBtnInfo.isShow;
    });

    /**
     * 搜索按钮
     */

    const isOperateRefreshBtn = computed(() => {
      const { operateRefreshBtn } = operationBtns.value || {};
      return operateRefreshBtn && operateRefreshBtn.isShow;
    });

    /**
     * 新增按钮参数
     */
    const paramsAdd = computed(() => {
      const { addBtnInfo } = operationBtns.value || {};
      return addBtnInfo && addBtnInfo.params;
    });

    /**
     *  是否展示容器
     */
    const isShowOperateContainer = computed(() => {
      return isShowAddBtn || isShowDelsBtn || isOperateRefreshBtn;
    });

    /**
     * 初始化搜索参数
     */
    const initQueryForm = () => {
      const { dataType, userId } = dataPerm;
      if (dataType == 0) {
        //0为机构，1为用户
        queryForm.value.IN_orgid = [orgid.value];
        return;
      }
      if (dataType == 1) {
        //0为机构，1为用户
        queryForm.value.EQ_cr = [userId];
        return;
      }
    };

    initQueryForm();

    /**
     * 转.字符串为对象赋值
     * @param {*} key
     */
    const setQueryFormHiddenValue = (key, value) => {
      const keys = key.split(".");
      console.info("22222222");
      const objKeys = keys.slice(0, -1); //置入对象targetKey
      const objKey = objKeys.reduce((pre, cur) => {
        //获取倒处一层key
        return pre ? pre[cur] : undefined;
      }, queryForm.value);

      console.info("333333333");
      objKey[keys.slice(-1)] = value; //赋值
    };

    /**
     * 获取隐藏字段
     */
    const getHiddenQuerys = () => {
      const { value } = querys || {};
      if (value && value.length) {
        for (const item of value) {
          if (item.type === FormStyle.HIDDEN) {
            const { name, value } = item;
            if (name.indexOf("." >= 0)) {
              setQueryFormHiddenValue(name, value);
            } else {
              queryForm.value[name] = value;
            }
          }
        }
      }
    };
    getHiddenQuerys();
    /**
     * searchKeys为外包掉用fetchData所传入参数
     */

    const fetchData = async params => {
      emit("update:is-loading", true);
      if ((customFetch && (typeof customFetch != "undefined" || customFetch.value)) || !queryUrl.value) {
        //由父组件自定义查询方法
        searchLoading.value = false;
        refreshLoading.value = false;
        emit("update:is-loading", false);
        emit("fetched-data");
      } else {
        const fetchFn = isUrlHasQuery ? queryList : getList;
        const res = await fetchFn(queryUrl.value, {
          ...queryForm.value,
          ...params
        });
        searchLoading.value = false;
        refreshLoading.value = false;
        emit("update:is-loading", false);
        if (res.code == 200) {
          emit("fetched-data", res);
        }
      }
    };

    const queryData = () => {
      searchLoading.value = true;
      if (queryForm.value.pageNum) {
        queryForm.value.pageNum = 1;
      }

      fetchData();
    };
    /**
     * 刷新数据
     */
    const onHandleRefresh = async () => {
      if (doRefresh.value) {
        refreshLoading.value = true;
        fetchData();
        return;
      }

      emit("refresh-data");
      //const res = await initData()
      //if (res.code == 200) {

      //}
    };

    /**
     * 新增按钮
     */
    const onHandleAdd = async () => {
      emit("handle-edit-info", operateType.ADD, paramsAdd.value);
    };

    const getMainUrl = () => {
      let url = queryUrl.value;
      if (isUrlHasQuery) {
        const urls = url.split("/").slice(0, -1);
        url = urls.join("/");
      }
      return url;
    };

    const onHandleDel = async () => {
      if (selectionIds && selectionIds.value.length) {
        const ids = selectionIds.value.map(item => item.id); // TODO:s是不是都是uuid
        const { DelsBtnInfo } = operationBtns.value || {};
        const url = getMainUrl();
        const { delUrl = url } = DelsBtnInfo || {};
        proxy.$baseConfirm("你确定要删除选中项吗", null, async () => {
          const loading = ElLoading.service({
            lock: true,
            text: "删除中，请稍候...",
            background: "rgba(0, 0, 0, 0.7)"
          });
          const { success, msg } = await doDelete(delUrl, ids);

          loading.close();
          if (success) {
            succMsg(msg);
            fetchData();
          } else {
            failMsg(msg);
          }
        });
      } else {
        proxy.$baseMessage("未选中任何行", "error", false, "vab-hey-message-error");
      }
    };

    const onHandleChangeValue = params => {
      const { isTriggerSearch } = params;
      if (isTriggerSearch) {
        queryData();
      }
      emit("on-handle-change-value", params);
    };

    onMounted(() => {
      const emitUrl = getMainUrl();
      if (emitUrl) {
        const eventName = pageName.value;
        $subFunc(`${eventName}queryData`, queryData);
      }
    });

    onUnmounted(() => {
      const eventName = pageName.value;
      $unsubFunc(`${eventName}queryData`);
    });

    watch(
      () => queryForm.value,
      newVal => {
        emit("update:model-value", { ...newVal });
      },
      { deep: true, immediate: true }
    );

    watch(
      () => props.isLoading,
      newVal => {
        searchLoading.value = newVal;
      },
      { deep: true, immediate: true }
    );

    watch(
      () => props.modelValue,
      (newVal, oldVal) => {
        if (JSON.stringify(props.modelValue) === JSON.stringify(queryForm.value)) return;
        queryForm.value = { ...props.modelValue };
        const { sorts, pageNum, pageSize } = newVal;
        const { sorts: oldSorts, pageNum: oldPageNo, pageSize: oldPageSize } = oldVal;

        if (sorts !== oldSorts || pageNum !== oldPageNo || pageSize !== oldPageSize) {
          fetchData();
        }
      },
      {
        deep: true
      }
    );

    if ((customFetch && (typeof customFetch != "undefined" || customFetch.value)) || !queryUrl.value) {
      //如果是自定义的不需操作
    } else {
      fetchData();
    }

    expose({ fetchData });
    return {
      pageName,
      isShowOperateContainer,
      isShowAddBtn,
      isShowDelsBtn,
      queryForm,
      isOperateRefreshBtn,
      refreshLoading,
      isShowSearchBtn,
      isShowRefreshBtn,
      querys,
      FormStyle,
      searchLoading,
      dataPerm,
      orgList,
      userIds,
      onHandleAdd,
      onHandleRefresh,
      onHandleDel,
      queryData,
      onHandleChangeValue,
      Search,
      Refresh,
      Delete,
      Plus
    };
  }
});
</script>

<style lang="scss" scoped>
.query-row {
  display: grid;
  grid-template: "operate search " 1fr / 1fr auto;
  width: 100%;
  &.up-down {
    grid-template: "search" auto "operate" auto / auto;
  }
  &.search-down {
    grid-template: "operate" auto "search" auto / auto;
  }
  :deep() {
    .el-date-editor {
      .el-input,
      .el-input__wrapper {
        width: 100%;
      }
    }
  }
  .operation-btns {
    grid-area: operate;
    :deep() {
      > button {
        margin-bottom: 15px;
      }
      span > button {
        margin-bottom: 15px;
      }
    }
  }
  .search-btns {
    display: flex;
    flex-wrap: wrap;
    grid-area: search;
    .query-input-rows {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      > div {
        margin-right: 15px;
        margin-bottom: 15px;
      }
      :deep() {
        > div {
          margin-right: 15px;
          margin-bottom: 15px;
        }
      }

      // > * {
      //   & + .query-btn-rows {
      //     margin-left: 15px;
      //   }
      // }
      .search-btn {
        margin-right: 15px;
        margin-bottom: 15px;
      }
    }

    // .query-btn-rows {
    //   > * {
    //     //margin-bottom: 15px;
    //   }
    // }
  }

  // .operation-btns {
  //   flex: 1;
  // }
  // .query-input-rows {
  //   display: flex;
  //   align-items: baseline;
  //   > div {
  //     display: flex;
  //     > div {
  //       margin-right: 15px;
  //     }
  //   }
  // }
  // .query-btns-rows {
  //   display: flex;
  // }
}
</style>
